package com.cnit1818.generator;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.sql.*;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: MaYong
 * Date: 12-11-20
 * Time: 上午11:01
 * To change this template use File | Settings | File Templates.
 */
@Component
public class CreateXMLFile {
    @Value("#{configProperties.ftlDir}")
    private String ftlDir;
    @Value("#{configProperties.mapperDir}")
    private String mapperDir;
    @Value("#{configProperties.entity}")
    private String entityDir;
    @Value("#{configProperties.xml}")
    private String xmlDir;

    private String getPackageStr(String string) {
        string = string.replace('.', '/');
        string = "/" + string;
        return string;
    }

    /**
     * 返回第一个字母大写的字符串
     *
     * @param tableName
     * @return
     */
    private String getTableName(String tableName) {
        tableName = tableName.toLowerCase();
        String tmp = "";
        boolean b = false;
        for (int i = 0; i < tableName.length(); i++) {
            String k = tableName.substring(i, i + 1);
            if (k.equals("_")) {
                b = true;
                continue;
            } else {
                if (b) {
                    tmp = tmp + k.toUpperCase();
                } else {
                    tmp = tmp + k.toLowerCase();
                }
                b = false;
            }
        }
        tmp = tmp.substring(0, 1).toUpperCase() + tmp.substring(1, tmp.length());
        return tmp;
    }

    private String getFieldName(String tableName) {
        tableName = tableName.toLowerCase();
        String tmp = "";
        boolean b = false;
        for (int i = 0; i < tableName.length(); i++) {
            String k = tableName.substring(i, i + 1);
            if (k.equals("_")) {
                b = true;
                continue;
            } else {
                if (b) {
                    tmp = tmp + k.toUpperCase();
                } else {
                    tmp = tmp + k.toLowerCase();
                }
                b = false;
            }
        }
        tmp = tmp.substring(0, 1).toLowerCase() + tmp.substring(1, tmp.length());
        return tmp;
    }

    /**
     * @param templateDir
     * @param translateTable
     * @param dataSource
     * @param tableName      原始的表名称
     * @throws IOException
     * @throws SQLException
     * @throws TemplateException
     */
    public void createXML(String templateDir, Hashtable<String, String> translateTable, DataSource dataSource,
                          String tableName)
            throws IOException, SQLException, TemplateException {
        File file = new File(mapperDir + getPackageStr(xmlDir) + "/" + getTableName(tableName) + ".xml");
        if (file.exists()) {
            System.out.println("文件存在 ---- 跳过XML ------");
            return;
        }
        System.out.println("文件不存在 -- 生成XML ------");
        MysqlTable mysqlTable = new MysqlTable();
        Configuration cfg = new Configuration();
        cfg.setDirectoryForTemplateLoading(new File(ftlDir));
        cfg.setObjectWrapper(new DefaultObjectWrapper());
//        Template temp = cfg.getTemplate("oracleMapper.ftl");
        Template temp = cfg.getTemplate("mysqlMapper.ftl");
        Connection connection = dataSource.getConnection();
        String sql = "select * from " + tableName + " where 2=3";
        Statement statement = connection.createStatement();
        ResultSet rs = statement.executeQuery(sql);
        ResultSetMetaData rsMetaData = rs.getMetaData();
        //拿到每个字段的注释值
        DatabaseMetaData databaseMetaData = connection.getMetaData();
        ResultSet databaseResultSet = databaseMetaData.getColumns(null, null, tableName.toUpperCase(), null);
//        ResultSet databaseResultSet = databaseMetaData.getColumns(null, databaseMetaData.getUserName().toUpperCase(), tableName.toUpperCase(), null);
        //获得表的主键
//        ResultSet keySet = connection.getMetaData().getPrimaryKeys(null, databaseMetaData.getUserName().toUpperCase(), tableName.toUpperCase());
        ResultSet keySet = connection.getMetaData().getPrimaryKeys(null, "", tableName.toLowerCase());
        String primaryKey = "";
        //可能多个主键
        while (keySet.next()) {
            primaryKey += keySet.getObject(4).toString().toLowerCase() + ",";
        }
        if (primaryKey.length() > 0) {
            primaryKey = primaryKey.substring(0, primaryKey.length() - 1);
        }
        keySet.close();
        //取主键结束
        List remarkList = new ArrayList();
        while (databaseResultSet.next()) {
            if (databaseResultSet.getString("REMARKS") == null) {
                remarkList.add("");
            } else {
                remarkList.add(databaseResultSet.getString("REMARKS"));
            }
        }
        //拿到每个字段的注释值end

        int count = rsMetaData.getColumnCount();
        Map<String, Object> root = new HashMap<String, Object>();
        root.put("class", getTableName(tableName));
        root.put("package", entityDir);
        root.put("key", primaryKey + "=#{" + getFieldName(primaryKey) + "}");
        Collection<Map<String, String>> properties = new HashSet<Map<String, String>>();
        root.put("properties", properties);
        String fieldNames = "\t";
        String srcNames = "\t";
        String fieldAndSrcNames = "select ";
        String key = "";
        for (int i = 1; i <= count; i++) {
            Map map = new HashMap();
            String type = rsMetaData.getColumnTypeName(i);
            type = translateTable.get(type);
            map.put("srcName", rsMetaData.getColumnName(i));
            map.put("name", getTableName(rsMetaData.getColumnName(i)));
            map.put("type", type);
//            map.put("memo", " //" + remarkList.get(i - 1));
            map.put("memo", " //");
            properties.add(map);

            fieldNames += rsMetaData.getColumnName(i) + ",\n\t\t\t";
            key = rsMetaData.getColumnName(i);
/*
            if (key.equals(primaryKey)) {
                srcNames += "#sid#,\n\t\t\t";
            } else {
*/
            String jdbcType = rsMetaData.getColumnTypeName(i);
            //add by MaYong 2016-11-04
            jdbcType = mysqlTable.getJdbcType(jdbcType);
            srcNames += "#{" + getFieldName(key) + ",jdbcType=" + jdbcType + "},\n\t\t\t";
//            }
            String field = rsMetaData.getColumnName(i);
            fieldAndSrcNames += field + " " + getFieldName(field) + ",\n\t\t\t";
        }
        fieldNames = fieldNames.substring(0, fieldNames.length() - ",\n\t\t\t".length());
        srcNames = srcNames.substring(0, srcNames.length() - ",\n\t\t\t".length());
        fieldAndSrcNames = fieldAndSrcNames.substring(0, fieldAndSrcNames.length() - ",\n\t\t\t".length());
        root.put("fieldNames", fieldNames);
        root.put("srcNames", srcNames);
        root.put("tableName", tableName);
        root.put("selectCount", "select count(1) as kk");
        root.put("fieldAndSrcNames", fieldAndSrcNames);
        Writer o = new FileWriter(file);
        temp.process(root, o);
        o.flush();
        databaseResultSet.close();
        rs.close();
        statement.close();
        connection.close();
    }
}
